/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       信号量优先级翻转实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 */

#include "userConfig.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"


/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   1024
TaskHandle_t    low_task_handler;

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   1024
TaskHandle_t    middle_task_handler;

/* TASK3 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   1024
TaskHandle_t    high_task_handler;

QueueHandle_t semphore_handle;

/* 任务一，低优先级任务 */
void low_task(void * pvParameters)
{
    while(1)
    {
        usart_transmit("low_task获取信号量\r\n");
        xSemaphoreTake(semphore_handle, portMAX_DELAY);
        usart_transmit("low_task正在运行!!!\r\n");
        vTaskDelay(3000);
        usart_transmit("low_task释放信号量\r\n");
        xSemaphoreGive(semphore_handle);
        vTaskDelay(1000);
    }
}

/* 任务二，中优先级任务 */
void middle_task(void * pvParameters)
{
    while(1)
    {
        usart_transmit("middle_task正在运行\r\n");
        vTaskDelay(1000);
    }
}

/* 任务三，高优先级任务 */
void high_task(void * pvParameters)
{
    while(1)
    {
        usart_transmit("high_task获取信号量\r\n");
        xSemaphoreTake(semphore_handle,portMAX_DELAY);
        usart_transmit("high_task正在运行\r\n");
        vTaskDelay(1000);
        usart_transmit("high_task释放信号量\r\n");
        xSemaphoreGive(semphore_handle);
        vTaskDelay(1000);
    }
}

static void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    xTaskCreate((TaskFunction_t         )   low_task,
                (char *                 )   "low_task",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &low_task_handler );

    xTaskCreate((TaskFunction_t         )   middle_task,
                (char *                 )   "middle_task",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &middle_task_handler );

    xTaskCreate((TaskFunction_t         )   high_task,
                (char *                 )   "high_task",
                (configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK3_PRIO,
                (TaskHandle_t *         )   &high_task_handler );

    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void semphore_binary_demo(void)
{
    semphore_handle = xSemaphoreCreateBinary();
    if(semphore_handle != NULL)
    {
        usart_transmit("二值信号量创建成功！！！\r\n");
    }
    xSemaphoreGive(semphore_handle);        /* 释放一次信号量 */

    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler);
    vTaskStartScheduler();
}
